package com.hdl.school.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ParseException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hdl.school.application.MyApplication;
import com.hdl.school.utils.CardReaderManager;
import com.hdl.school.utils.Constants;
import com.hdl.school.utils.TCWManager;
import com.hdl.school.utils.TimeUtil;
import com.leectrl.utils.Bus;
import com.leectrl.utils.StorageManager;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

public class OuterMqttService extends Service {
    private MqttClient mqttClient;
    private String appid=null;
    private String deviceId=null;
    private MyReceiver myReceiver;
    private SharedPreferences sharedPreferences;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 6:
                    //中控升级固件
                    Intent intent1 = new Intent("com.leectrl.app.update");
                    intent1.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
                    intent1.putExtra("mediaUrl", (String) msg.obj);
                    intent1.putExtra("installPackageName", "com.hdl.school.schoolcontroller");
                    sendBroadcast(intent1);
                    break;
                case 7:
                    Intent intent7 = new Intent(Constants.ACTION_CARDCHECKED);
                    intent7.putExtra("checked", (int) msg.obj);
                    sendBroadcast(intent7);
                    break;
                case 8:
                    Intent intent8 = new Intent(Constants.ACTION_BROAD_LOCK_EVENT);
                    intent8.putExtra("lock",true);
                    sendBroadcast(intent8);
                    break;
                case 9:
                    Intent intent9 = new Intent(Constants.ACTION_BROAD_LOCK_EVENT);
                    intent9.putExtra("lock",false);
                    sendBroadcast(intent9);
                    break;
            }
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        sharedPreferences=getSharedPreferences("school_iot", 0);
        appid=sharedPreferences.getString("APPID",null);
        deviceId=sharedPreferences.getString("DEVICEID",null);
        if (appid == null) {
            appid = "lt123gh5623";
        }
        deviceId = sharedPreferences.getString("c_setting_DEVICEID", null);
        if (deviceId == null) {
            deviceId = UUID.randomUUID().toString().replaceAll("-", "");
            sharedPreferences.edit().putString("c_setting_DEVICEID", deviceId).commit();
        }
        String outerMqtt = sharedPreferences.getString("c_setting_mqtt", null);
        if(outerMqtt!=null){
            final JSONObject mqttConfig= JSON.parseObject(outerMqtt);
            if(mqttConfig!=null&&mqttConfig.containsKey("enable")&&mqttConfig.getString("enable").equals("on")){
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        connectMqttServer(mqttConfig);
                    }
                }).start();
                Timer timer=new Timer();
                timer.scheduleAtFixedRate(new TimerTask() {
                    @Override
                    public void run() {
                        if (mqttClient != null && (!mqttClient.isConnected())) {
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    connectMqttServer(mqttConfig);
                                }
                            }).start();
                        }

                    }
                },15000,30000);
            }
        }
        IntentFilter intentFilter = new IntentFilter(Constants.ACTION_SERIALSTATUS);
        intentFilter.addAction(Constants.ACTION_CARDSLOT);
        intentFilter.addAction(Constants.ACTION_LOG);
        myReceiver = new MyReceiver();
        registerReceiver(myReceiver, intentFilter);
        Bus.getInstance().on("publish_feedback_msg", new Bus.MessageEvent() {
            @Override
            public void onEvent(String key, Object... message) {
                JSONObject obj = (JSONObject) message[0];
                publishMessage("/gatetway/"+appid+"/"+deviceId+"/event/device/status",JSON.toJSONString(obj));
            }
        });
    }

    private  void connectMqttServer(JSONObject mqttConfig) {
        if (mqttClient != null) {
            try {
                mqttClient.close(true);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
        try {
            mqttClient = new MqttClient("tcp://" + mqttConfig.getString("host") + ":"+mqttConfig.getString("port"), "terminal_"+(new Date()).getTime(), new MemoryPersistence());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(true);
            options.setUserName(mqttConfig.getString("username"));
            options.setPassword(mqttConfig.getString("password").toCharArray());
            // 设置超时时间
            options.setConnectionTimeout(10);
            // 设置会话心跳时间
            options.setKeepAliveInterval(20);
            options.setAutomaticReconnect(false);
            JSONObject willObject=new JSONObject();
            willObject.put("action","DEVICE_ONLINE_STATUS");
            JSONObject actionData=new JSONObject();
            actionData.put("deviceID",deviceId);
            actionData.put("online",0);
            willObject.put("actionData",actionData);
            options.setWill("/gatetway/" + appid + "/" + deviceId + "/action/will/notify",JSON.toJSONString(willObject).getBytes(),1,true);
            mqttClient.connect(options);
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable throwable) {

                }

                @Override
                public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                    String topicStr = topic;
                    String payloadStr = null;
                    try {
                        payloadStr = (new String(mqttMessage.getPayload(), "UTF-8"));
                        Log.e("MqttService", topicStr + "==>" + payloadStr);
                        String[] topicArr = topicStr.split("/");
                        if(topicStr.endsWith("/time/resp")){
                            JSONObject resp=JSON.parseObject(payloadStr);
                            long time = resp.getLongValue("time");
                            Date date = new Date(time);
                            TCWManager.getInstance(MyApplication.myApplication).setTime(1900 + date.getYear(), date.getMonth() + 1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
                        }else if(topicStr.endsWith("/device/ctrl")){
                            JSONObject cmd=JSON.parseObject(payloadStr);
                            if(cmd.containsKey("action")&&cmd.containsKey("protocol")){
                                String action=cmd.getString("action");
                                Bus.getInstance().emit("exec_action", action, cmd.getJSONObject("params"), cmd.getString("protocol"), 5);
                                JSONObject jsonObject=new JSONObject();
                                jsonObject.put("action","FEEDBACK_ACTION_LOG");
                                JSONObject logData=new JSONObject();
                                logData.put("deviceID",deviceId);
                                logData.put("userType","NETWORK");
                                logData.put("userAccount","admin");
                                String command=null;
                                if("in_class".equals(action)){
                                    command="SYS_POWER_ON";
                                }else if("over_class".equals(action)){
                                    command="SYS_POWER_OFF";
                                }else if("cast_open".equals(action)){
                                    command="PROJECTOR_ON";
                                }else if("cast_close".equals(action)){
                                    command="PROJECTOR_OFF";
                                }else if("cloth_down".equals(action)){
                                    command="SCREEN_DOWN";
                                }else if("cloth_up".equals(action)){
                                    command="SCREEN_UP";
                                }else if("close_comp".equals(action)){
                                    command="PC_POWER_OFF";
                                }else if("open_comp".equals(action)){
                                    command="PC_POWER_ON";
                                }else if("show_comp".equals(action)){
                                    command="SIGNAL_PC";
                                }else if("show_booth".equals(action)){
                                    command="SIGNAL_DIGITAL_STAGE";
                                }else if("show_mobilepc".equals(action)){
                                    command="SIGNAL_LAPTOP";
                                }else if("voice_up".equals(action)){
                                    command="VOL_INC";
                                }else if("voice_down".equals(action)){
                                    command="VOL_DEC";
                                }else if("open_light".equals(action)){
                                    command="LIGHT_ON";
                                }else if("close_light".equals(action)){
                                    command="LIGHT_OFF";
                                }
                                logData.put("command",command);
                                logData.put("time",TimeUtil.getCurTimeToString("yyyy-MM-dd HH:mm:ss"));
                                jsonObject.put("actionData",logData);
                                publishMessage("/gatetway/" + appid + "/" + deviceId + "/event/action/log", JSON.toJSONString(jsonObject));
                            }
                        } else if (topicStr.endsWith("/card/check")) {
                            JSONObject cmd = JSON.parseObject(payloadStr);
                            int isLegal=cmd.getIntValue("is_legal");
                            Message msg=new Message();
                            msg.what=7;
                            msg.obj=isLegal;
                            handler.sendMessage(msg);
                        } else if (topicStr.endsWith("/controller/setting")) {
                            JSONObject actionObj = JSON.parseObject(payloadStr);
                            if (actionObj.containsKey("action")) {
                                String action = actionObj.getString("action");
                                if ("set_lock_mode".equals(action)&&actionObj.containsKey("mode")) {
                                    String mode=actionObj.getString("mode");
                                    sharedPreferences.edit().putString("lock_mode",mode ).commit();
                                    CardReaderManager.getInstance().setCheckMode(mode);
                                    JSONObject object = new JSONObject();
                                    object.put("status", "success");
                                    object.put("action", "set_lock_mode");
                                    publishMessage("/gatetway/" + appid + "/" + deviceId + "/event/setting/resp", JSON.toJSONString(object));
                                } else if ("schedule_download".equals(action)) {
                                    String url = actionObj.getString("url");
                                    RequestParams requestParams = new RequestParams(url);
                                    requestParams.setAsJsonContent(true);
                                    JSONObject body = new JSONObject();
                                    body.put("device_id", deviceId);
                                    requestParams.setBodyContent(JSON.toJSONString(body));
                                    x.http().post(requestParams, new Callback.CommonCallback<String>() {
                                        @Override
                                        public void onSuccess(final String result) {
                                            new Thread(new Runnable() {
                                                @Override
                                                public void run() {
                                                    try {
                                                        JSONObject jsonObject = JSONObject.parseObject(result);
                                                        StorageManager.getInstance().setItem("schedule",result);
                                                        JSONObject object = new JSONObject();
                                                        object.put("status", "success");
                                                        object.put("action", "schedule_download");
                                                        publishMessage("/gatetway/" + appid + "/" + deviceId + "/event/setting/resp", JSON.toJSONString(object));
                                                    } catch (Exception e) {

                                                    }
                                                }
                                            }).start();
                                        }

                                        @Override
                                        public void onError(Throwable ex, boolean isOnCallback) {

                                        }

                                        @Override
                                        public void onCancelled(CancelledException cex) {

                                        }

                                        @Override
                                        public void onFinished() {

                                        }
                                    });
                                } else if ("upgrade_app".equals(action)) {
                                    if (actionObj.containsKey("url")) {
                                        Message message1 = new Message();
                                        message1.what = 6;
                                        message1.obj = actionObj.getString("url");
                                        handler.sendMessage(message1);
                                    }

                                }
                            }

                        }

                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

                }

            });
            subscribeTopic("/gatetway/"+appid+"/"+deviceId+"/action/time/resp");
            subscribeTopic("/gatetway/"+appid+"/"+deviceId+"/action/device/ctrl");
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("action","reqTime");
            publishMessage("/gatetway/"+appid+"/"+deviceId+"/action/time/req",JSON.toJSONString(jsonObject));
        }catch (Exception e) {
            e.printStackTrace();
        }


    }

    public void publishMessage(String topic,String msg){
        try {
            if(mqttClient!=null&&mqttClient.isConnected()){
                MqttMessage message = new MqttMessage();
                message.setQos(1);
                message.setRetained(true);
                message.setPayload(msg.getBytes());
                MqttTopic mqttTopic = mqttClient.getTopic(topic);
                MqttDeliveryToken token = mqttTopic.publish(message);//发布主题
                token.waitForCompletion();
            }

        } catch (MqttPersistenceException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (MqttException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }


    public  void subscribeTopic(String topicStr) {
        // Subscribe to a topic foo
        try {
            mqttClient.subscribe(topicStr);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        if (myReceiver != null) {
            unregisterReceiver(myReceiver);
        }
        super.onDestroy();
    }

    class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (Constants.ACTION_CARDSLOT.equals(action)) {
                publishMessage("/gatetway/" + appid + "/" + deviceId + "/event/card/slot", intent.getStringExtra("data"));
            } else if (Constants.ACTION_LOG.equals(action)) {
                JSONObject jsonObject=new JSONObject();
                jsonObject.put("action","FEEDBACK_ACTION_LOG");
                JSONObject logData=new JSONObject();
                logData.put("deviceID",deviceId);
                boolean remote=intent.getBooleanExtra("remote",false);
                logData.put("userType",remote?"NETWORK":"LOCAL");
                logData.put("userAccount",remote?"admin":"user");
                logData.put("command",intent.getStringExtra("command"));
                logData.put("time", TimeUtil.getCurTimeToString("yyyy-MM-dd HH:mm:ss"));
                jsonObject.put("actionData",logData);
                publishMessage("/gatetway/" + appid + "/" + deviceId + "/event/action/log", JSON.toJSONString(jsonObject));
            }
        }
    }
}